/*
 * This file is part of LangMan.
 *
 * LangMan is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * LangMan is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LangMan.  If not, see <http://www.gnu.org/licenses/>.
 */

package langman.business.actions;

import langman.business.actions.category.AddCategoryAction;
import langman.business.actions.category.EditCategoryAction;
import langman.business.actions.category.RemoveCategoryAction;
import langman.business.actions.common.Action;
import langman.business.actions.common.ActionTypes;
import langman.business.actions.defaults.DefaultAddAction;
import langman.business.actions.defaults.DefaultEditAction;
import langman.business.actions.defaults.DefaultRemoveAction;
import langman.business.actions.key.AddKeyAction;
import langman.business.actions.key.EditKeyAction;
import langman.business.actions.key.RemoveKeyAction;
import langman.business.actions.save.SaveAction;
import langman.util.doping.Context;
import langman.util.doping.Inject;
import langman.util.doping.SingletonBean;

import java.util.EnumMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@SingletonBean
public class ActionFactory {

    private final Map<ActionTypes, Action> actions = new EnumMap<>(ActionTypes.class);
    private final Context context;

    @Inject
    public ActionFactory(Context context) {
        this.context = context;
    }

    @Inject
    public void searchProducts() {
        Set<Class<? extends Action>> actionTypes = getActionTypes();

        for (Class<? extends Action> aClass : actionTypes) {
            Action action = context.getBean(aClass);
            actions.put(action.getActionType(), action);
        }
    }

    /*
     * To circumvent a bug in reflections which makes it not pick up on all the subtypes of Action
     */
    private Set<Class<? extends Action>> getActionTypes() {
        Set<Class<? extends Action>> subTypesOf = new HashSet<>();
        subTypesOf.add(AddCategoryAction.class);
        subTypesOf.add(EditCategoryAction.class);
        subTypesOf.add(RemoveCategoryAction.class);
        subTypesOf.add(DefaultAddAction.class);
        subTypesOf.add(DefaultRemoveAction.class);
        subTypesOf.add(DefaultEditAction.class);
        subTypesOf.add(AddKeyAction.class);
        subTypesOf.add(EditKeyAction.class);
        subTypesOf.add(RemoveKeyAction.class);
        subTypesOf.add(AddCategoryAction.class);
        subTypesOf.add(EditCategoryAction.class);
        subTypesOf.add(RemoveCategoryAction.class);
        subTypesOf.add(SaveAction.class);
        return subTypesOf;
    }

    public Action getAction(ActionTypes actionType) {
        if (actions.containsKey(actionType)) {
            return actions.get(actionType);
        }
        return actions.get(ActionTypes.Null);
    }
}
